﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using Galaktika.BI.Runtime.Services;
using Galaktika.BI.Runtime;
using Galaktika.BI.Charting;
using Galaktika.BI.Charting.PivotChart;
using Galaktika.BI.Silverlight.Controls.General;
using Galaktika.BI.Silverlight.Intermediate;
using System.Collections.ObjectModel;
using Galaktika.BI.Silverlight.Controls.OLAP.Descriptions;
using Galaktika.BI.Silverlight.Controls.Data;
using Ranet.Olap.Core;
using Ranet.Olap.Core.Data;
using Galaktika.BI.Silverlight.Intermediate.Charting;
using Galaktika.BI.Extensibility.Dom;
using Ranet.AgOlap.Controls.ContextMenu;
using Galaktika.BI.Silverlight.Services;
using Galaktika.BI.Silverlight.Controls.PivotGrid;
using Galaktika.BI.Silverlight.Charting;
using Ranet.Olap.Core.Providers.ClientServer;
using Ranet.AgOlap.Controls.General;
using Ranet.AgOlap.Controls.DataSourceInfo;
using Ranet.AgOlap.Controls.Forms;
using Visifire.Charts;

namespace Galaktika.BI.Silverlight.Controls.Charting
{
    public partial class RanetChart : UserControl, IEditableObject, IBindableObject
    {
       private static IAppManager service;
        private static Dictionary<string, PaletteCollection> paletteRepository;
        private Storyboard resDoubleClickTimer;
        private DataPoint m_SelectedDataPoint;
        private PivotDataLoaderEx m_PivotDataLoader;
        private ChartingCommon chartingCommon;

        public RanetChart()
        {
            ALegendBorderColor = Colors.Transparent;
            InitializeComponent();

            this.chartingCommon = new ChartingCommon(this.chart);

            this.Legend = new Legend();
            this.ALegendFont = new Font();
            this.ALegendFont.Size = 11;          
            this.ACaptionFont.Size = 13;
            this.ASeries = new ChartSeriesCollection();
            this.ASeries.Add(new ChartSeries());
            //
            // events
            //
            resDoubleClickTimer = new Storyboard();
            resDoubleClickTimer.Duration = new Duration(TimeSpan.FromMilliseconds(250.0));
            resDoubleClickTimer.Completed += new EventHandler(resDoubleClickTimer_Completed);

            this.chart.MouseLeftButtonDown += chart_MouseLeftButtonDown;
            this.chart.MouseLeftButtonUp += chart_MouseLeftButtonUp;
            this.chart.DrillDown += chart_DrillDown;

            this.AttachContextMenu(p =>
            {
                 return this.ContextMenu;
            }
            );            
            this.chart.ChartExceptionRaised += chart_ChartExceptionRaised;
        }


        void chart_DrillDown(object sender, DrillDownEventArgs args)
        {
            if (args != null && args.DataPoint != null)
            {
                this.m_SelectedDataPoint = args.DataPoint;
                if (this.m_SelectedDataPoint != null)
                {
                    this.ContextMenu.Tag = this.m_SelectedDataPoint;
                    this.chartingCommon.ParseArgsOnMenuItems(this.ContextMenu);
                }
            }
        }

        void chart_ChartExceptionRaised(object sender, ChartCombinationEventArgs e)
        {
            e.Handled = true;
            var s = (IOutputService)this.Context.Services.GetService(typeof(IOutputService));
            if (s != null)
            {
                s.WriteException(e.ChartException);
            }
        }

        public object ADataSource
        {
            get;
            set;
        }     

        public CustomList<ActionInfo> AActionInfo { get; set; }

        //[DefaultValue(false)]
        [Obsolete]
        public bool AIsFilterMode { get; set; }

        [DefaultValue(false)]
        public bool AAutoGenerateSeries { get; set; }

        private ViewType m_DiagramType = ViewType.Bar;
        public ViewType ADiagramType
        {
            get { return m_DiagramType; }
            set { m_DiagramType = value; }
        }

        [Obsolete]
        public string APointsFilter { get; set; }

        [DefaultValue("")]
        public string AToolTipText { get; set; }

        public bool AShowToolTips { get; set; }

        public Axis AxisX { get; set; }

        public Axis AxisY { get; set; }

        public Legend Legend { get; set; }

        #region Series properties

        private ChartSeriesCollection m_Series;

        public ChartSeriesCollection ASeries
        {
            get
            {
                if (m_Series == null)
                {
                    m_Series = new ChartSeriesCollection();
                }

                return m_Series;
            }
            set
            {
                if (m_Series == null)
                {
                    m_Series = new ChartSeriesCollection();
                }

                m_Series = value.Clone();
            }
        }



        #endregion

        #region Diagram Properties
    
        public bool ADiagramRotated { get; set; }

        private Color m_DiagramBackColor = Colors.White;
        public Color ADiagramBackColor
        {
            get
            {
                return m_DiagramBackColor;
            }
            set
            {
                m_DiagramBackColor = value;
            }
        }


        public Color ADiagramBorderColor { get; set; }

        public bool ADiagramBorderVisible { get; set; }

        public bool AEnabledZooming { get; set; }

        #endregion Diagram Properties

        #region Legend Properties

        public bool ALegendVisible { get; set; }

        private Color m_LegendBackColor = Colors.Transparent;
        public Color ALegendBackColor
        {
            get
            {
                return m_LegendBackColor;
            }
            set
            {
                m_LegendBackColor = value;
            }
        }


        private Color m_LegendForeColor = Colors.Black;
        public Color ALegendColor
        {
            get
            {
                return m_LegendForeColor;
            }
            set
            {
                this.m_LegendForeColor = value;
            }
        }

        private Font m_LegendFont;
        public Font ALegendFont
        {
            get
            {
                return m_LegendFont;
            }
            set
            {
                if (value != null)
                {
                    m_LegendFont = value;
                }
            }
        }

        private bool m_LegendBorderVisible = true;
        [DefaultValue(true)]
        public bool ALegendBorderVisible
        {
            get
            {
                return m_LegendBorderVisible;
            }
            set
            {
                m_LegendBorderVisible = value;
                if (!value)
                    this.ALegendBorderThickness = 0;
            }
        }

        public Color ALegendBorderColor { get; set; }

        private int m_LegendBorderThickness = 1;
        public int ALegendBorderThickness
        {
            get
            {
                return m_LegendBorderThickness;
            }
            set
            {
                m_LegendBorderThickness = value;
            }
        }

        [Obsolete]
        public bool ALegendMarkerVisible
        {
            get;
            set;
        }


        [Obsolete]
        public bool ALegendShadowVisible { get; set; }


        [Obsolete]
        public Color ALegendShadowColor { get; set; }

        [Obsolete]
        public int ALegendShadowSize { get; set; }


        private LegendAlignmentHorizontal m_LegendAlignmentHorizontal = LegendAlignmentHorizontal.Right;
        public LegendAlignmentHorizontal ALegendAlignmentHorizontal
        {
            get
            {
                return m_LegendAlignmentHorizontal;
            }
            set
            {
                m_LegendAlignmentHorizontal = value;
            }
        }

        private LegendAlignmentVertical m_LegendAlignmentVertical = LegendAlignmentVertical.Center;
        public LegendAlignmentVertical ALegendAlignmentVertical
        {
            get
            {
                return m_LegendAlignmentVertical;
            }
            set
            {
                m_LegendAlignmentVertical = value;
            }
        }

        [Obsolete]
        public bool ALegendAntialiasing { get; set; }

        public LegendDirection ALegendDirection
        {
            get;
            set;
        }

        [DefaultValue(2)]
        [Obsolete]
        public int ALegendSpacingHorizontal { get; set; }

        [DefaultValue(2)]
        [Obsolete]
        public int ALegendSpacingVertical { get; set; }


        [DefaultValue(100)]
        [Obsolete]
        public double ALegendMaxHorizontalPercentage { get; set; }

        [DefaultValue(100)]
        [Obsolete]
        public double ALegendMaxVerticalPercentage { get; set; }

        #endregion Legend Properties

        #region AxisX Properties

        public bool AAxisXVisible
        {
            get;
            set;
        }

        public bool AAxisXGridLinesVisible
        {
            get;
            set;
        }

        [DefaultValue(false)]
        [Obsolete]
        public bool AAxisXInterlaced { get; set; }

        [Obsolete]
        public Color AAxisXInterlacedColor { get; set; }

        [DefaultValue(false)]
        public bool AAxisXReverse { get; set; }

        public bool AAxisXShowZero { get; set; }
    
        [Obsolete]
        public bool AAxisXTitleAntialiasing { get; set; }

        [DefaultValue(false)]
        [Obsolete]
        public bool AAxisXLabelAntialiasing { get; set; }

        public int AAxisXLabelAngle { get; set; }

        private Font m_AxisXLabelFont = new Font();
        public Font AAxisXLabelFont
        {
            get { return m_AxisXLabelFont; }
            set
            {
                if (value != null)
                {
                    m_AxisXLabelFont = value;
                }
            }
        }

        public bool AAxisXLabelStaggered { get; set; }

        private double? m_AxisXInterval = 1;
        public double? AAxisXInterval
        {
            get
            {
                return
                m_AxisXInterval;

            }
            set
            {
                m_AxisXInterval = value;
            }
        }

        private int m_AxisXPointsCount = 0;
        public int AAxisXPointsCount
        {
            get
            {
                return 100;
            }
            set
            {
                //this.AxisX.Maximum = value;
            }
        }

        [DefaultValue(typeof(NumericFormat), "General")]
        public NumericFormat AAxisXFormat
        {
            get
            {
                return NumericFormat.General;
            }
            set
            { 
            }
        }

        private int m_AxisXFormatPrecision = 2;
        public int AAxisXFormatPrecision
        {
            get { return m_AxisXFormatPrecision; }
            set { m_AxisXFormatPrecision = value; }
        }

        [Obsolete]
        public bool AAxisXGridSpacingAuto { get; set; }

        private bool AxisXIsDateTimeAxis;

        #endregion AxisX Properties

        #region AxisY Properties
  
        public bool AAxisYVisible
        {
            get;
            set;
        }

        public bool AAxisYGridLinesVisible
        {
            get;
            set;
        }

        [Obsolete]
        public bool AAxisYInterlaced { get; set; }

        [Obsolete]
        public Color AAxisYInterlacedColor { get; set; }

        [DefaultValue(false)]
        public bool AAxisYReverse { get; set; }

        public bool AAxisYShowZero { get; set; }    

        [Obsolete]
        public bool AAxisYTitleAntialiasing { get; set; }

        [Obsolete]
        public bool AAxisYLabelAntialiasing { get; set; }

        public int AAxisYLabelAngle { get; set; }

        private Font m_AxisYLabelFont = new Font();
        public Font AAxisYLabelFont
        {
            get { return m_AxisYLabelFont; }
            set
            {
                if (value != null)
                {
                     m_AxisYLabelFont = value;
                }
            }
        }

        public bool AAxisYLabelStaggered { get; set; }

        private double? m_AxisYInterval = 1;
        public double? AAxisYInterval
        {
            get
            {
                return m_AxisYInterval;
            }
            set
            {
                m_AxisYInterval = value;
            }
        }

        public int AAxisYPointsCount { get; set; }

        [DefaultValue(typeof(NumericFormat), "General")]
        public NumericFormat AAxisYFormat
        {
            get
            {
                return NumericFormat.General;
            }
            set
            {
                //this.AxisY.IntervalType = AxisIntervalType.Auto;               
            }
        }


        private int m_AxisYFormatPrecision = 2;
        public int AAxisYFormatPrecision
        {
            get { return m_AxisYFormatPrecision; }
            set { m_AxisYFormatPrecision = value; }
        }

        [Obsolete]
        public bool AAxisYGridSpacingAuto { get; set; }

        #endregion AxisY Properties

        #region Appearance Properties
  
        public bool AVisible
        {
            get
            {
                if (this.chart != null)
                {
                    return this.Visibility == Visibility.Visible;
                }
                return false;
            }
            set
            {
                this.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        [DefaultValue("")]
        public string ACaption
        {
            get;
            set;
        }

        private bool m_CaptionVisible;
        [DefaultValue(false)]
        public bool ACaptionVisible
        {
            get
            {
                return m_CaptionVisible;
            }
            set
            {
                m_CaptionVisible = value;
            }
        }

        private Color m_CaptionColor = DefaultColors.Black;
        [DefaultValue(typeof(Color), "Black")]
        public Color ACaptionColor
        {
            get
            {
                return m_CaptionColor;
            }
            set
            {
                m_CaptionColor = value;
            }
        }

        private Font m_CaptionFont = new Font();
        public Font ACaptionFont
        {
            get { return m_CaptionFont; }
            set
            {
                if (value != null)
                {
                    m_CaptionFont = value;
                }
            }
        }

        [Obsolete]
        public bool ACaptionAntialiasing { get; set; }

        private Color m_BackColor;
        public Color ABackColor
        {
            get
            {
                return m_BackColor;
            }
            set
            {
                m_BackColor = value;
            }
        }

        private Color m_BorderColor;
        [DefaultValue(typeof(Color), "Transparent")]
        public Color ABorderColor
        {
            get
            {
                return m_BorderColor;
            }
            set
            {
                this.m_BorderColor = value;
             }
        }


        private int m_BorderThickness = 1;
        [DefaultValue(1)]
        public int ABorderThickness
        {
            get
            {
                return m_BorderThickness;
            }
            set
            {
                m_BorderThickness = value;
            }
        }

        private bool m_BorderVisible;
        [DefaultValue(true)]
        public bool ABorderVisible
        {
            get
            {
                return m_BorderVisible;
            }
            set
            {
                m_BorderVisible = value;
                if (!value)
                    this.ABorderThickness = 0;
            }
        }


        public Cursor ACursor
        {
            get { return base.Cursor; }
            set { base.Cursor = value; }
        }

        [DefaultValue("Standart")]
        public string APaletteName { get; set; }

        public PaletteCollection AUserPalette { get; set; }

        void PaletteCollectionModified(object sender, EventArgs e)
        {
            // обновляю палитры графика
            //this.UpdateChartPalettes();

            // перерисовываю график случайными числами
            // this.RedrawChart();
        }
        #endregion Appearance Properties


        private byte m_ClickCount = 0;
        MouseButtonEventArgs m_LastArgs;
        void resDoubleClickTimer_Completed(object sender, EventArgs e)
        {
            if (m_ClickCount > 1)
            {
                this.OnMouseDoubleClick(m_LastArgs);
            }
            m_ClickCount = 0;
        }

        void chart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            m_ClickCount++;
            m_LastArgs = e;
            resDoubleClickTimer.Begin();
        }

        void chart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.OnMouseClick(e);
        }      

        CustomContextMenu m_ContextMenu;
        public CustomContextMenu ContextMenu
        {
            get
            {
                if (m_ContextMenu == null)
                {
                    m_ContextMenu = new CustomContextMenu();
                    ReCreateContextMenu(m_ContextMenu);
                    Raise_ContextMenuCreated();
                }
                return m_ContextMenu;
            }
        }

        private void ReCreateContextMenu(CustomContextMenu contextMenu)
        {
            contextMenu.Items.Clear();

            if (this.AActionInfo != null && this.AActionInfo.Count > 0)
            {
                foreach (ActionInfo info in this.AActionInfo)
                {
                    if (info.ACaption.Contains("---"))
                    {
                        contextMenu.AddMenuSplitter();
                    }
                    else
                    {
                        var item2 = new ContextMenuItem(info.ACaption);
                        item2.ItemClick += new EventHandler(SeriesAreaContextMenu_ItemClick);
                        item2.Tag = info;
                        item2.Icon = null;
                        contextMenu.AddMenuItem(item2);
                    }
                }
                if (contextMenu.Items.Count > 0)
                {
                    contextMenu.AddMenuSplitter();
                }
            }

            //item = new ContextMenuItem(Localization.Mnu_Customize);
            //item.Tag = this.CustomizeWindow;
            //contextMenu.AddMenuItem(item);
            //item.ItemClick += new EventHandler(CustomizeItem_ItemClick);

            ContextMenuItem item = new ContextMenuItem(Localization.Mnu_Zooming);
            item.Tag = this.AEnabledZooming;
            contextMenu.AddMenuItem(item);
            item.ItemClick += new EventHandler(ZoomingItem_ItemClick);
            contextMenu.AddMenuSplitter();

            ContextMenuItem showMDX = new ContextMenuItem(Localization.Mnu_ShowMDX);
            //item.Tag = this.AEnabledZooming;
            contextMenu.AddMenuItem(showMDX);
            showMDX.ItemClick += new EventHandler(ShowMDX_ItemClick);         

            ContextMenuItem export = new ContextMenuItem(Localization.AppTask_ExportToExcel);
            contextMenu.AddMenuItem(export);
            export.ItemClick += new EventHandler(Export_ItemClick);
            //return contextMenu;
        }

        void Export_ItemClick(object sender, EventArgs e)
        {
            ExportToExcel();
        }

        private void ExportToExcel()
        {
            var args = new ServiceCommandArgs(ServiceCommandType.ExportToExcel);
            var dataLoaderEx = new PivotDataLoaderEx(this);
            dataLoaderEx.Context = this.Context;
            IBindingManager manager = null;
            this.Bindings.TryGetValue("ADataSource", out manager);
            dataLoaderEx.BindManager = manager;
            dataLoaderEx.PerformServiceCommand(XmlSerializationUtility.Obj2XmlStr(args, Common.Namespace), args);
        }

        void ShowMDX_ItemClick(object sender, EventArgs e)
        {
            GetDataSourceInfo();
        }

        private void ZoomingItem_ItemClick(object sender, EventArgs e)
        {
            if (((ContextMenuItem) sender).Tag is bool)
            {
                ((ContextMenuItem) sender).Tag = !(bool)((ContextMenuItem) sender).Tag;
                this.AEnabledZooming = (bool)((ContextMenuItem) sender).Tag;
            }
            if (this.AEnabledZooming)
            {
                ((ContextMenuItem) sender).Icon = UriResources.Images.ActionNode16;
                this.zoomScroll.Visibility = Visibility.Visible;
                //TODO: Реализовать Zooming
                return;
            }
            this.zoomScroll.Visibility = Visibility.Collapsed;
            ((ContextMenuItem) sender).Icon = null;
        }

        private void CustomizeItem_ItemClick(object sender, EventArgs e)
        {
            //TODO: Реализовать настройку.
        }


        public event EventHandler ContextMenuCreated;
        private void Raise_ContextMenuCreated()
        {
            EventHandler handler = this.ContextMenuCreated;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }


        void SeriesAreaContextMenu_ItemClick(object sender, EventArgs e)
        {
            var item = sender as ContextMenuItem;
            this.m_SelectedDataPoint = null;
            if (item != null && item.Tag != null)
            {
                if (item.Tag is ActionInfo)
                {
                    var ai = item.Tag as ActionInfo;
                    if (ai != null && ai.AActionInvoker != null &&
                        ((BrickActionInvoker)ai.AActionInvoker).Action != null)
                    {
                        var args =
                            new List<ArgumentEntry>(((BrickActionInvoker)ai.AActionInvoker).Parameters);

                        var mi = this.ContextMenu.Tag as DataPoint;
                        if (mi != null)
                        {
                            foreach (var arg in this.chartingCommon.GetContextArgs(mi, mi.Parent))
                            {
                                args.Add(new ArgumentEntry(arg.Key, arg.Value));
                            }
                        }
                        ScriptEngine.Execute(new MockCaller(this.Context),
                                             ((BrickActionInvoker)ai.AActionInvoker).Action, args);
                    }
                    return;
                }
            }
        }
     
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public event MouseButtonEventHandler MouseDoubleClick;
        protected void OnMouseDoubleClick(MouseButtonEventArgs e)
        {
            if (this.MouseDoubleClick != null)
            {
                this.MouseDoubleClick(this, e);
            }
        }

        public event MouseButtonEventHandler MouseClick;
        protected void OnMouseClick(MouseButtonEventArgs e)
        {
            if (this.MouseClick != null)
            {
                this.MouseClick(this, e);
            }
        }

        private void AddToChartSeriesAddedFromDesign()
        {
            this.chart.Series.Clear();
            for (int index = 0; index < m_DesignData.Count; index++)
            {
                var chartSeries = this.ASeries[index];
                if (chartSeries != null)
                {
                    DataSeries[] seriesArrayFromDataSource = this.chartingCommon.GetSeriesFromDataSourceFlat(this.ADataSource,chartSeries.AViewType,string.Empty,this.ALegendVisible);
                    if (this.IndexInArrayRange(chartSeries.ADataSeriesIndex, seriesArrayFromDataSource))
                    {
                        var series = seriesArrayFromDataSource[chartSeries.ADataSeriesIndex];
                        if (RanetSeriesFactory.IsSeriesWithAxes(chartSeries))
                        {
                            series.RenderAs = RanetSeriesFactory.GetSeriesType(chartSeries);
                            series = ApplyToSeriesViewSettingsFromDesign(chartSeries, series);
                            this.chart.Series.Add(series);
                          }
                        else
                        {
                            series.RenderAs = RanetSeriesFactory.GetSeriesType(chartSeries);
                            series = ApplyToSeriesViewSettingsFromDesign(chartSeries, series);
                            if (!(this.chart.Series.Count > 0))
                                this.chart.Series.Add(series);
                          }

                    }
                }
            }
        }

        private DataSeries ApplyToSeriesViewSettingsFromDesign(ChartSeries chartSeries, DataSeries series)
        {
            if (RanetSeriesFactory.IsUsed3D(chartSeries))
                this.chart.View3D = true;
            if (this.ADiagramRotated)
                series.RenderAs = RanetSeriesFactory.RotateSeriesType(chartSeries.AViewType);
            return series;
        }

        // Входит ли индекс index в границы массива array
        private bool IndexInArrayRange(int index, DataSeries[] array)
        {
            if ((index >= 0) && (index < array.Length))
            {
                return true;
            }
            return false;
        }

        private void AddToChartSeriesAutogenerateFromDataSource(DataSeries[] seriesArrayFromDataSource)
        {
            this.chart.Series.Clear();
            for (int index = 0; index < seriesArrayFromDataSource.Length; index++)
            {
                var series = seriesArrayFromDataSource[index];
                var chartSeries = new ChartSeries();
                chartSeries.AViewType = this.ADiagramType;                
                if (this.ADiagramRotated)
                    series.RenderAs = RanetSeriesFactory.RotateSeriesType(chartSeries.AViewType);
                else
                    series.RenderAs = RanetSeriesFactory.GetSeriesType(chartSeries);
                this.chart.Series.Add(series);
           }
        }

        public void UpdateChartPalettes()
        {            
            chartingCommon.UpdateChartPalettes(this.APaletteName,this.Context);
        }                

        public void RefreshChart()
        {
            var taskMgr = (IUserTaskManager)this.Context.Services.GetService(typeof(IUserTaskManager));
            var exe = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
            if (exe != null && taskMgr != null)
            {
                taskMgr.RunTaskAsync(
                    string.Format(Localization.AppTask_ProcessingProperties, base.Name),
                    state =>
                    {
                        string text = exe.Parse(this.Context, this.ACaption);
                        taskMgr.Dispatcher.BeginInvoke(() =>
                        {
                            this.UpdateChartPalettes();

                            if (AAutoGenerateSeries)
                                AddToChartSeriesAutogenerateFromDataSource(m_DesignData.ToArray());
                            else
                                AddToChartSeriesAddedFromDesign();

                            this.chart.Titles.Clear();
                            if (this.ACaptionVisible)
                            {
                                var chartTitle = new Title();
                                chartTitle.Text = text;
                                if (!String.IsNullOrEmpty(this.ACaptionFont.FamilyName))
                                {
                                    chartTitle.FontFamily = new FontFamily(this.ACaptionFont.FamilyName);
                                    chartTitle.FontSize = this.ACaptionFont.Size;
                                    if (this.ACaptionFont.Italic)
                                    {
                                        chartTitle.FontStyle = FontStyles.Italic;
                                    }
                                    if (this.ACaptionFont.Bold)
                                    {
                                        chartTitle.FontWeight = FontWeights.Bold;
                                    }
                                }
                                chartTitle.Foreground =
                                    new SolidColorBrush(this.ACaptionColor);
                                this.chart.Titles.Add(chartTitle);
                            }
                            // свойства внешнего вида для области графика

                            this.chart.Background =
                                new SolidColorBrush(this.ABackColor);

                            //Свойства диаграммы
                            if (this.AEnabledZooming)
                            {

                                //TODO: Реализовать масштабирование графика
                            }

                            //Ось X 
                            bool isPie = false;
                            foreach (var s in this.chart.Series)
                            {                             
                                s.SelectionEnabled = true;
                                if (s.RenderAs == RenderAs.Pie || s.RenderAs == RenderAs.Doughnut)
                                {
                                    s.StartAngle = 270;
                                    isPie = true;
                                }
                            }
                           
                            if (!isPie)
                            {
                                this.chart.AxesX[0].Enabled = this.AAxisXVisible;
                                this.chart.AxesY[0].Enabled = this.AAxisYVisible;
                                if (this.AxisXIsDateTimeAxis)
                                    this.chart.AxesX[0].AxisLabels.IsAxisDateTime = true;
                                if (this.AAxisXLabelAngle != 0)
                                    this.chart.AxesX[0].AxisLabels.Angle = this.AAxisXLabelAngle;
                                if (this.AAxisYLabelAngle != 0)
                                    this.chart.AxesY[0].AxisLabels.Angle = this.AAxisYLabelAngle;
                                if (this.AAxisXLabelStaggered)
                                    this.chart.AxesX[0].AxisLabels.Rows = 2;
                                else
                                    this.chart.AxesX[0].AxisLabels.Rows = 1;

                                this.chart.AxesY[0].StartFromZero = this.AAxisYShowZero;
                            }
                                
                            // Легенда
                            foreach (var l in this.chart.Legends)
                            {
                                switch (this.ALegendDirection)
                                {
                                    case LegendDirection.BottomToTop:
                                    case LegendDirection.TopToBottom:
                                        l.Orientation = Orientation.Vertical;
                                        break;
                                    case LegendDirection.LeftToRight:
                                    case LegendDirection.RightToLeft:
                                        l.Orientation = Orientation.Horizontal;
                                        break;
                                }

                                switch (this.ALegendAlignmentHorizontal)
                                {
                                    case LegendAlignmentHorizontal.Center:
                                        l.HorizontalAlignment = HorizontalAlignment.Center;
                                        break;
                                    case LegendAlignmentHorizontal.Left:
                                        l.HorizontalAlignment = HorizontalAlignment.Left;
                                        break;
                                    case LegendAlignmentHorizontal.Right:
                                        l.HorizontalAlignment = HorizontalAlignment.Right;
                                        break;
                                    case LegendAlignmentHorizontal.LeftOutside:
                                        l.HorizontalAlignment = HorizontalAlignment.Left;
                                        l.DockInsidePlotArea = false;
                                        break;
                                    case LegendAlignmentHorizontal.RightOutside:
                                        l.HorizontalAlignment = HorizontalAlignment.Right;
                                        l.DockInsidePlotArea = false;
                                        break;
                                }

                                switch (this.ALegendAlignmentVertical)
                                { 
                                    case LegendAlignmentVertical.Bottom:
                                        l.VerticalAlignment = VerticalAlignment.Bottom;
                                        break;
                                    case LegendAlignmentVertical.Center:
                                        l.VerticalAlignment = VerticalAlignment.Center;
                                        break;
                                    case LegendAlignmentVertical.Top:
                                        l.VerticalAlignment = VerticalAlignment.Top;
                                        break;
                                    case LegendAlignmentVertical.BottomOutside:
                                        l.VerticalAlignment = VerticalAlignment.Bottom;
                                        l.DockInsidePlotArea = false;
                                        break;
                                    case LegendAlignmentVertical.TopOutside:
                                        l.VerticalAlignment = VerticalAlignment.Top;
                                        l.DockInsidePlotArea = false;
                                        break;
                                }
                                
                                if (!String.IsNullOrEmpty(this.ALegendFont.FamilyName))
                                {
                                    l.FontFamily = new FontFamily(this.ALegendFont.FamilyName);
                                    l.FontSize = this.ALegendFont.Size;
                                    if (this.ALegendFont.Italic)
                                        l.FontStyle = FontStyles.Italic;
                                    if (this.ALegendFont.Bold)
                                        l.FontWeight = FontWeights.Bold;
                                }
                                l.Enabled = this.ALegendVisible;                                
                            }
                         });
                    });
            }
            ReCreateContextMenu(this.ContextMenu);
        }

        private bool UseZooming
        {
            get
            {
                return this.AEnabledZooming;
            }
        }              

        void GetDataSourceInfo()
        {
            ServiceCommandArgs args = new ServiceCommandArgs(ServiceCommandType.GetDataSourceInfo, null);
            m_PivotDataLoader.PerformServiceCommand(XmlSerializationUtility.Obj2XmlStr(args, Common.Namespace), args);
        }

        void Loader_DataLoaded(object sender, DataLoaderEventArgs e)
        {
            try
            {
                if (e.Error != null)
                {
                    return;
                }

                if (e.Result.ContentType == InvokeContentType.Error)
                {
                    return;
                }

                var serviceArgs = e.UserState as ServiceCommandArgs;
                if (serviceArgs != null)
                {
                    ServiceCommandType actionType = serviceArgs.Command;
                    if (actionType == ServiceCommandType.GetDataSourceInfo)
                    {
                        if (!string.IsNullOrEmpty(e.Result.Content))
                        {
                            var info = XmlSerializationUtility.XmlStr2Obj<DataSourceInfoArgs>(e.Result.Content);
                            ShowDataSourceInfo(info);
                        }
                        return;
                    }
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        void ShowDataSourceInfo(DataSourceInfoArgs args)
        {
            if (args != null)
            {
                var dlg = new ModalDialog();
                //dlg.Caption = Localization.DataSourceInfoDialog_Caption;
                dlg.MinHeight = 300;
                dlg.MinWidth = 400;
                dlg.Height = 400;
                dlg.Width = 500;

                var dsInfo = new DataSourceInfoControl();
                dlg.Content = dsInfo;
                dsInfo.Initialize(args);

                dlg.Show();
            }
        }


        #region IEditableObject Members

        public void BeginEdit()
        {

        }

        public void CancelEdit()
        {

        }
    
        List<DataSeries> m_DesignData;

        public void EndEdit()
        {
            IBindingManager manager = null;
            this.Bindings.TryGetValue("ADataSource", out manager);
            m_DesignData = new List<DataSeries>();
            m_PivotDataLoader = new PivotDataLoaderEx(this) { Context = this.Context, BindManager = manager };
            m_PivotDataLoader.DataLoaded += Loader_DataLoaded;
            m_DesignData = chartingCommon.ProcessPivotTable(this.ADataSource, this.ADiagramType, string.Empty, this.ALegendVisible);//this.ProcessPivotTable();
            RefreshChart();
        }

        #endregion

        #region IBindableObject Members

        public IBindingContext Context { get; set; }

        private IDictionary<string, IBindingManager> m_Bindings;
        public IDictionary<string, IBindingManager> Bindings
        {
            get
            {
                if (m_Bindings == null)
                {
                    m_Bindings = new SafeDictionary<string, IBindingManager>();
                }

                return m_Bindings;
            }
        }

        #endregion

        #region Методы для работы с реальными данными 

        /// <summary>
        /// Возвращает текущую позицию IBindingManager
        /// </summary>
        /// <returns></returns>
        private int[] GetCurrentPosition()
        {
            IBindingManager manager = this.Bindings["ADataSource"];
            if (manager != null)
            {
               return manager.Position;
            }
            return new int[] { 0 };
        }
        #endregion Методы для работы с реальными данными

        private void zoomScroll_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {

        }
    }
}

